# -*- coding: utf-8 -*-
import os
import signal

import psutil

import win32service
import win32serviceutil

from global_data.glabal_data import GlobalData
from utils.icloudp_log import IcloudpLog


class SystemTools(object):
    def __init__(self):
        super(self).__init__()

    @staticmethod
    def process_exists(process_name):
        """
        判断进程是否存在
        :param process_name:
        :return:
        """
        # 转换进程名为小写，避免大小写敏感的问题
        process_name = process_name.lower()
        for proc in psutil.process_iter(['name']):
            # 同样将进程名转换为小写
            if proc.info['name'].lower() == process_name:
                return True
        return False

    @staticmethod
    def get_proc(process_name):
        """
        获取进程信息
        :param process_name:
        :return:
        """
        pass

    @staticmethod
    def get_proc_info(process_name):
        """
        获取进程详细信息
        :param process_name:
        :return: 返回字典  id 名称 cpu使用情况 内存使用情况
        """
        infos = {}
        # 转换进程名为小写，避免大小写敏感的问题
        process_name = process_name.lower()
        # 打印系统上所有进程的信息
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            # 获取进程信息
            pinfo = proc.info
            if pinfo['name'].lower() == process_name:
                infos["pid"] = pinfo["pid"]
                infos["name"] = pinfo["name"]
                infos["cpu_percent"] = f"{pinfo['cpu_percent']:.2f}%"
                infos["memory_percent"] = f"{pinfo['memory_percent']:.2f}%"
                return infos
        return None


    @staticmethod
    def get_proc_info_all(process_name):
        """
        获取进程详细信息  多进程
        :param process_name:
        :return: 返回字典  id 名称 cpu使用情况 内存使用情况
        """
        list_info = []
        infos = {}
        # 转换进程名为小写，避免大小写敏感的问题
        process_name = process_name.lower()
        # 打印系统上所有进程的信息
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            # 获取进程信息
            pinfo = proc.info
            if pinfo['name'].lower() == process_name:
                infos["pid"] = pinfo["pid"]
                infos["name"] = pinfo["name"]
                infos["cpu_percent"] = f"{pinfo['cpu_percent']:.2f}%"
                infos["memory_percent"] = f"{pinfo['memory_percent']:.2f}%"
                list_info.append(infos)
        return list_info

    @staticmethod
    def get_proc_info_str(process_name):
        """
        获取进程详情情况
        :param process_name:
        :return:
        """
        # 转换进程名为小写，避免大小写敏感的问题
        process_name = process_name.lower()
        info = SystemTools.get_proc_info(process_name)
        infos = ""
        if info is not None:
            infos = infos + f"进程id={info['pid']}\n"
            infos = infos + f"进程名称={info['name']}\n"
            infos = infos + f"CPU使用情况={info['cpu_percent']}\n"
            infos = infos + f"内存使用情况={info['memory_percent']}\n"
        return infos


    @staticmethod
    def get_proc_infos_count(procs):
        """
        获取所有进程数量
        :param procs:
        :return:
        """
        list_info = []
        count = 0
        procs_lower = list(map(lambda x: x.lower(), procs))
        # 打印系统上所有进程的信息
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            # 获取进程信息
            pinfo = proc.info
            if pinfo['name'].lower() in procs_lower:
                count = count + 1
        return count

    @staticmethod
    def get_proc_infos(procs):
        """
        获取所有进程信息
        :param procs:
        :return:
        """
        list_info = []
        procs_lower = list(map(lambda x: x.lower(), procs))
        # 打印系统上所有进程的信息
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            # 获取进程信息
            pinfo = proc.info
            if pinfo['name'].lower() in procs_lower:
                infos = {"pid": pinfo["pid"],
                         "name": pinfo["name"],
                         "cpu_percent": f"{pinfo['cpu_percent']:.2f}%",
                         "memory_percent": f"{pinfo['memory_percent']:.2f}%"}
                list_info.append(infos)
        return list_info

    @staticmethod
    def get_procs_info_str(procs):
        """
        获取进程详情情况
        :param process_name:
        :return:
        """
        proc_info = {}
        infos = SystemTools.get_proc_infos(procs)
        for info in infos:
            proc_info[info["name"].lower()] = f"进程id={info['pid']}\n" + \
                                                    f"进程名称={info['name']}\n" + \
                                                    f"CPU使用情况={info['cpu_percent']}\n" + \
                                                    f"内存使用情况={info['memory_percent']}"
        return proc_info

    @staticmethod
    def kill_proc(process_name, is_force=False):
        """
        结束进程
        :param process_name:
        :param is_force:  是否强制结束
        :param proc_name: 进程名
        :return:
        """
        # 转换进程名为小写，避免大小写敏感的问题
        process_name = process_name.lower()
        procs = SystemTools.get_proc_info_all(process_name)
        if len(procs) > 0:
            for proc in procs:
                print(f"cs进程id={proc['pid']}")
                # 结束指定PID的进程
                if is_force:
                    os.kill(proc["pid"], 9)
                else:
                    os.kill(proc["pid"], signal.SIGTERM)

    def get_services_statu_str(service_name):
        try:
            status = win32serviceutil.QueryServiceStatus(service_name)[1]
            return GlobalData.SERVICE_STATUS[status]
        except Exception as e:
            IcloudpLog.error(f"检测服务错误：{e}")
            return "系统错误或者服务不存在"


    def get_service_status(service_name):
        # 获取服务状态
        status = win32serviceutil.QueryServiceStatus(service_name)[1]
        # 状态码解释：
        # 1 - STOPPED
        # 2 - START_PENDING
        # 3 - STOP_PENDING
        # 4 - RUNNING
        # 5 - CONTINUE_PENDING
        # 6 - PAUSE_PENDING
        # 7 - PAUSED
        return status

    def start_service(service_name):
        # 启动服务
        win32serviceutil.StartService(service_name)

    def stop_service(service_name):
        # 停止服务
        win32serviceutil.StopService(service_name)

    def restart_service(service_name):
        # 重启服务
        win32serviceutil.RestartService(service_name)


if __name__ == '__main__':
    print("Python")
